package com.travelingsalesmen.post.gui;

import com.travelingsalesmen.post.*;
import com.travelingsalesmen.post.rmi.IServer;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;

public class GUIPost extends javax.swing.JFrame implements IPost {

    private Catalog catalog;
    private Transaction currentTransaction;
    private List<Invoice> newInvoices = new ArrayList<Invoice>();
    private IServer server;
    private ActionListener payListener = new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent ae) {
            String type = pnlPayment.getPaymentType();
            String extraInfo = pnlPayment.getPaymentExtraInfo();
            pay(type, extraInfo);
        }
    };
    private ActionListener addItemListener = new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent ae) {
            int quantity = pnlProduct.getQuantity();
            String upc = pnlProduct.getUPC();
            try {
                addItem(upc, quantity);
            } catch (RemoteException ex) {
                Logger.getLogger(GUIPost.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    };

    /**
     * Creates new form GUIPost
     */
    public GUIPost() {
        initComponents();
        pnlProduct.setAddItemListener(addItemListener);
        pnlPayment.setPayActionListener(payListener);
    }

    public void connectToServer(IServer server) {
        this.server = server;
    }

    @Override
    public void start() {
        startNewTransaction();
        setVisible(true);
    }

    public final void startNewTransaction() {
        currentTransaction = new Transaction();
        currentTransaction.setPost(this);
        lblDate.setText(currentTransaction.getDate().toString());
        txtCustomerName.setText("");
        pnlInvoice.reset();
        pnlPayment.reset();
        pnlProduct.reset();
    }

    private void addItem(String UPC, int quantity) throws RemoteException {
        currentTransaction.addItem(UPC, quantity);
        Item item = new Item(catalog.getSpec(UPC), quantity);
        pnlInvoice.addItem(item.getDescription(), item.getUnitCost(), quantity, item.getSubtotal(), currentTransaction.getTotal());
    }

    public Item scanItem(String upc, int quantity) {
        ProductSpec ps = catalog.getSpec(upc);
        return new Item(ps, quantity);
    }

    public void pay(String type, String extraInfo) {
        String customerName = txtCustomerName.getText();
        if (customerName == null || customerName.trim().equals("")) {
            JOptionPane.showMessageDialog(null, "Please set a customer name");
            return;
        }
        currentTransaction.setName(customerName);

        if (extraInfo == null || extraInfo.trim().equals("")) {
            JOptionPane.showMessageDialog(null, "Plese enter payment information");
            return;
        }

        boolean paymentSuccessful = currentTransaction.pay(type, extraInfo);
        if (paymentSuccessful) {
            JOptionPane.showMessageDialog(null, "Transaction was successful.  Press ok to start next transaction");
        } else {
            JOptionPane.showMessageDialog(null, "Payment failed.  Press ok to start next transaction.");
        }

        System.out.print(currentTransaction);

        Invoice invoice = new Invoice(currentTransaction);

        try {
            server.uploadInvoice(invoice);
            uploadCachedInvoices();
        } catch (NullPointerException e) {
            // Not logged into server
            newInvoices.add(invoice);
        } catch (RemoteException e) {
            newInvoices.add(invoice);
        }

        startNewTransaction();
    }

    /**
     * Try to upload any cached invoices and remove them if they are
     * successfully uploaded
     */
    public void uploadCachedInvoices() {
        if (newInvoices.isEmpty()) {
            // No cached invoices to upload
            return;
        }

        for (Invoice invoice : newInvoices) {
            try {
                server.uploadInvoice(invoice);
                newInvoices.remove(invoice);
            } catch (RemoteException ex) {
                Logger.getLogger(GUIPost.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public void getCatalogFromServer() throws RemoteException {
        if (server == null) {
            throw new RemoteException("Not logged into server");
        }
        setCatalog(server.getCatalog());
    }

    public void setCatalog(Catalog catalog) {
        this.catalog = catalog;
        pnlProduct.populateList(catalog);
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        lblCustomerName = new javax.swing.JLabel();
        txtCustomerName = new javax.swing.JTextField();
        lblStoreName = new javax.swing.JLabel();
        lblDate = new javax.swing.JLabel();
        pnlProduct = new com.travelingsalesmen.post.gui.ProductPanel();
        pnlInvoice = new com.travelingsalesmen.post.gui.InvoicePanel();
        pnlPayment = new com.travelingsalesmen.post.gui.PaymentPanel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("The Traveling Bake Shop POST Terminal");
        setResizable(false);

        lblCustomerName.setFont(new java.awt.Font("Tahoma", 1, 12)); // NOI18N
        lblCustomerName.setText("Customer Name");
        lblCustomerName.setName("lblCustomerName"); // NOI18N

        txtCustomerName.setName("txtCustomerName"); // NOI18N

        lblStoreName.setFont(new java.awt.Font("Tahoma", 1, 18)); // NOI18N
        lblStoreName.setText("The Traveling Bake Shop");
        lblStoreName.setName("lblStoreName"); // NOI18N

        lblDate.setText("Date"); // NOI18N
        lblDate.setName("lblDate"); // NOI18N

        pnlProduct.setName("pnlProduct"); // NOI18N

        pnlInvoice.setName("pnlInvoice"); // NOI18N

        pnlPayment.setName("pnlPayment"); // NOI18N

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createSequentialGroup()
                                .addGap(10, 10, 10)
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addGroup(layout.createSequentialGroup()
                                        .addComponent(lblCustomerName)
                                        .addGap(26, 26, 26)
                                        .addComponent(txtCustomerName, javax.swing.GroupLayout.PREFERRED_SIZE, 163, javax.swing.GroupLayout.PREFERRED_SIZE))
                                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                                        .addComponent(lblDate, javax.swing.GroupLayout.PREFERRED_SIZE, 127, javax.swing.GroupLayout.PREFERRED_SIZE)
                                        .addGap(97, 97, 97))))
                            .addGroup(layout.createSequentialGroup()
                                .addGap(36, 36, 36)
                                .addComponent(lblStoreName)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)))
                        .addComponent(pnlProduct, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(pnlInvoice, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(pnlPayment, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(24, 24, 24)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(lblStoreName)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(lblDate, javax.swing.GroupLayout.PREFERRED_SIZE, 37, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(23, 23, 23)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(lblCustomerName)
                            .addComponent(txtCustomerName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                    .addComponent(pnlProduct, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(pnlInvoice, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(pnlPayment, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel lblCustomerName;
    private javax.swing.JLabel lblDate;
    private javax.swing.JLabel lblStoreName;
    private com.travelingsalesmen.post.gui.InvoicePanel pnlInvoice;
    private com.travelingsalesmen.post.gui.PaymentPanel pnlPayment;
    private com.travelingsalesmen.post.gui.ProductPanel pnlProduct;
    private javax.swing.JTextField txtCustomerName;
    // End of variables declaration//GEN-END:variables
}
